package com.xw.controller.callbackcontroller;

import cn.hutool.core.util.NumberUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.xw.dao.*;
import com.xw.model.*;
import com.xw.util.AppUtil;
import com.xw.util.PropertiesUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

@Controller
@RequestMapping("/aliPayCallBack")
public class AlipayCallBackController {

    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private OrdersItemMapper ordersItemMapper;
    @Autowired
    private VideosMapper videosMapper;
    @Autowired
    private PlatformBillMapper platformBillMapper;
    @Autowired
    private BasicSetMapper basicSetMapper;
    @Autowired
    private BuyVideosMapper buyVideosMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserBillMapper userBillMapper;

    /**
     * 支付订单
     * @param request
     * @param response
     * @throws AlipayApiException
     * @throws IOException
     */
    @RequestMapping(value = "/payOrders",method = RequestMethod.POST)
    public void payOrders(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, IOException {
        PrintWriter pw = response.getWriter();
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        //      params回调里面的参数
        // {
        //     "app_id": "2018050760145056",
        //         "auth_app_id": "2018050760145056",
        //         "body": "我是测试数据",
        //         "buyer_id": "2088302254644666",
        //         "buyer_logon_id": "318***@qq.com",
        //         "buyer_pay_amount": "0.01",
        //         "charset": "UTF-8",
        //         "fund_bill_list": "[{\"amount\":\"0.01\",\"fundChannel\":\"ALIPAYACCOUNT\"}]",
        //         "gmt_create": "2018-06-27 15:01:05",
        //         "gmt_payment": "2018-06-27 15:01:05",
        //         "invoice_amount": "0.01",
        //         "notify_id": "cad82bd6cc769bdec88c9880813933al3h",
        //         "notify_time": "2018-06-27 15:01:06",
        //         "notify_type": "trade_status_sync",
        //         "out_trade_no": "201806271501006045",  自己生成的订单号
        //         "point_amount": "0.00",
        //         "receipt_amount": "0.01",
        //         "seller_email": "lingquanshijie@lingquanshijie.com",
        //         "seller_id": "2088031559404832",
        //         "subject": "App支付测试Java",
        //         "total_amount": "0.01",
        //         "trade_no": "2018062721001004660536492208",
        //         "trade_status": "TRADE_SUCCESS",
        //         "version": "1.0"
        // }
        // 程序执行完后必须打印输出“success”（不包含引号）。如果商户反馈给支付宝的字符不是success这7个字符，支付宝服务器会不断重发通知，直到超过24小时22分钟。
        // 一般情况下，25小时以内完成8次通知（通知的间隔频率一般是：2m,10m,10m,1h,2h,6h,15h）；

        //切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean flag = AlipaySignature.rsaCheckV1(params, PropertiesUtil.getProperty("ALIPAY_PUBLICKEY"), "UTF-8","RSA2");
        if (flag) {
            //判断付款状态 trade_status 为TRADE_SUCCESS 成功
            if ("TRADE_SUCCESS".equals(params.get("trade_status"))) {
                //自己生成的订单号
                String out_trade_no = params.get("out_trade_no");
                //支付宝生成的订单号
                String trade_no = params.get("trade_no");

                Orders model = new Orders();
                model.setOrderNo(out_trade_no);
                Orders orders = ordersMapper.selectOne(model);
                //订单状态: 0-已取消， 1-待付款，2-已付款(已完成)
                orders.setStatus(2);
                orders.setPaymentTime(new Date());
                ordersMapper.updateByPrimaryKeySelective(orders);

                //更新销量 根据订单查询购买的哪个视频
                List<String> videosIdList = ordersItemMapper.findVideosIdByOrdersNo(out_trade_no);
                if (videosIdList.size() > 0){
                    for (String s : videosIdList) {
                        Videos videos = videosMapper.selectByPrimaryKey(s);
                        videos.setSaleCount(videos.getSaleCount() + 1);
                        videosMapper.updateByPrimaryKeySelective(videos);

                        //添加购买视频记录
                        BuyVideos buyVideos = new BuyVideos();
                        buyVideos.setId(AppUtil.uuid());
                        buyVideos.setUserId(orders.getUserId());
                        buyVideos.setVideosId(s);
                        buyVideosMapper.insertSelective(buyVideos);

                        //付款之后将一部分抽成记录到账单表中
                        BasicSet basicSet = basicSetMapper.selectAll().get(0);
                        //抽成的钱
                        double mul = NumberUtil.mul(basicSet.getPercent(), orders.getPayment());
                        PlatformBill bill = new PlatformBill();
                        bill.setId(AppUtil.uuid());
                        bill.setBillType(0);
                        bill.setMoney(mul);
                        bill.setOrdersNo(out_trade_no);
                        bill.setCreateTime(new Date());
                        platformBillMapper.insertSelective(bill);

                        //给视频发布者钱，90%
                        double sub = NumberUtil.sub(orders.getPayment(), (Double) mul);
                        String videosUserId = videos.getUserId();
                        User videosUser = userMapper.selectByPrimaryKey(videosUserId);
                        videosUser.setBalance(NumberUtil.add(videosUser.getBalance(),(Double) sub));
                        userMapper.updateByPrimaryKeySelective(videosUser);

                        //添加用户账单
                        UserBill userBill = new UserBill();
                        userBill.setId(AppUtil.uuid());
                        userBill.setUserId(videosUserId);
                        userBill.setBillTitle("视频收入-" + videos.getVideoName());
                        //设置账单类型 0. 加 1.减
                        userBill.setBillType(0);
                        userBill.setMoney(sub);
                        userBill.setCreateTime(new Date());
                        userBill.setFromUserId("0");
                        userBill.setFlag(2);
                        //0.未付款 1.已付款
                        userBill.setPayStatus(1);
                        //0.余额 1.支付宝 2.微信
                        userBill.setPayType(2);
                        userBill.setOrdersNo(out_trade_no);
                        userBill.setTransactionId(trade_no);
                        userBillMapper.insertSelective(userBill);
                    }
                }



                pw.write("success");
                pw.flush();
                pw.close();
            } else {
                pw.write("success");
                pw.flush();
                pw.close();
            }
        }else {
            //释放资源
            pw.write("success");
            pw.flush();
            pw.close();
        }
    }


    /**
     * 支付宝回调案例
     * @param request
     * @param response
     * @throws AlipayApiException
     * @throws IOException
     */
    @RequestMapping(value = "/test",method = RequestMethod.POST)
    public void test(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, IOException {
        PrintWriter pw = response.getWriter();
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        //      params回调里面的参数
        // {
        //     "app_id": "2018050760145056",
        //         "auth_app_id": "2018050760145056",
        //         "body": "我是测试数据",
        //         "buyer_id": "2088302254644666",
        //         "buyer_logon_id": "318***@qq.com",
        //         "buyer_pay_amount": "0.01",
        //         "charset": "UTF-8",
        //         "fund_bill_list": "[{\"amount\":\"0.01\",\"fundChannel\":\"ALIPAYACCOUNT\"}]",
        //         "gmt_create": "2018-06-27 15:01:05",
        //         "gmt_payment": "2018-06-27 15:01:05",
        //         "invoice_amount": "0.01",
        //         "notify_id": "cad82bd6cc769bdec88c9880813933al3h",
        //         "notify_time": "2018-06-27 15:01:06",
        //         "notify_type": "trade_status_sync",
        //         "out_trade_no": "201806271501006045",  自己生成的订单号
        //         "point_amount": "0.00",
        //         "receipt_amount": "0.01",
        //         "seller_email": "lingquanshijie@lingquanshijie.com",
        //         "seller_id": "2088031559404832",
        //         "subject": "App支付测试Java",
        //         "total_amount": "0.01",
        //         "trade_no": "2018062721001004660536492208",
        //         "trade_status": "TRADE_SUCCESS",
        //         "version": "1.0"
        // }
        // 程序执行完后必须打印输出“success”（不包含引号）。如果商户反馈给支付宝的字符不是success这7个字符，支付宝服务器会不断重发通知，直到超过24小时22分钟。
        // 一般情况下，25小时以内完成8次通知（通知的间隔频率一般是：2m,10m,10m,1h,2h,6h,15h）；

        //切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean flag = AlipaySignature.rsaCheckV1(params, PropertiesUtil.getProperty("ALIPAY_PUBLICKEY"), "UTF-8","RSA2");
        if (flag) {
            //判断付款状态 trade_status 为TRADE_SUCCESS 成功
            if ("TRADE_SUCCESS".equals(params.get("trade_status"))) {
                //自己生成的订单号
                String out_trade_no = params.get("out_trade_no");

                pw.write("success");
                pw.flush();
                pw.close();
            } else {
                pw.write("success");
                pw.flush();
                pw.close();
            }
        }else {
            //释放资源
            pw.write("success");
            pw.flush();
            pw.close();
        }
    }


}
